package server

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net"
	"os"
	"protocol/common"
	"strings"
)

var connects = make(map[string]net.Conn)

// StartServer 启动server
func StartServer(host string, port int) {
	//1.监听端口
	address := fmt.Sprintf("%s:%d", host, port)
	fmt.Println("connect address", address)
	listener, err := net.Listen("tcp", address)
	if err != nil {
		fmt.Println("listen failed, err:", err)
		return
	}
	fmt.Println("server started")
	defer func() {
		listener.Close()
		fmt.Println("server服务退出")
	}()

	//监控控制台
	go func() {
		reader := bufio.NewReader(os.Stdin)
		for {
			data, err := reader.ReadString('\n')
			if err != nil {
				fmt.Printf("read from console failed, err:%v\n", err)
				break
			}
			broadcast(data)
		}
	}()

	for {
		//2.接收客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Printf("accept failed, err:%v\n", err)
			continue
		}
		//3.开启Goroutine处理连接
		go process(conn)
	}

}

// 处理请求，类型就是net.Conn
func process(conn net.Conn) {

	//处理结束后关闭链接
	defer conn.Close()
	for {
		var buf [4096]byte
		n, err := conn.Read(buf[:])
		if err != nil {
			fmt.Printf("read from conn failed, err: %v", err)
			break
		}
		var message common.Message
		err = json.Unmarshal(buf[:n], &message)
		if err != nil {
			fmt.Printf("parse message error: %v\n", err)
		}
		fmt.Printf("recv from client, content: %v\n", string(buf[:n]))
		doProcess(conn, buf[:n])
	}
}

// 执行处理逻辑
func doProcess(conn net.Conn, bytes []byte) {
	message := common.ParseBytes[common.Message](bytes)
	if message.MessageType == common.ESTABLISH_CONNECTION {
		fmt.Println("处理建立连接消息")
		body := message.Body
		if len(body) == 0 {
			fmt.Errorf("establish connection error ,no connect info")
			return
		}
		connectMessage := common.ParseString[common.ConnectMessage](message.Body)
		connects[connectMessage.Name] = conn
		fmt.Printf("接受客户端连接成功,%s \n", connectMessage.Name)
	} else if message.MessageType == common.HEARTBEAT {
		heartbeatMessage := common.ParseString[common.HeartbeatMessage](message.Body)
		fmt.Printf("receive %s heartbeat", heartbeatMessage.ConnectMessage.Name)
		//todo 通过心跳状态，更新connects数据
	} else if message.MessageType == common.SEND_MESSAGE {
		fmt.Println("处理发送消息消息")
		sendMessage := common.ParseString[common.SendMessage](message.Body)
		sender := sendMessage.Sender
		receivers := sendMessage.Receivers
		body := sendMessage.Body
		if len(sender) == 0 {
			fmt.Errorf("sender is nil")
			return
		}
		if len(receivers) == 0 {
			fmt.Errorf("receiver is nil")
			return
		}
		if len(body) == 0 {
			return
		}
		for _, receiver := range receivers {
			connect := connects[receiver]
			if connect == nil {
				fmt.Printf("receiver :%s is offineline", receiver)
				// todo 消息持久化
				continue
			}
			receiverMessage := common.SendMessage{Sender: sender, Body: body}
			connect.Write(common.BuildMessageForType(common.SEND_MESSAGE, nil, receiverMessage))
		}
	}
}

// 广播消息
func broadcast(content string) {
	for k, v := range connects {
		fmt.Println(k, v)
		_, err := v.Write([]byte(strings.TrimSpace(content)))
		if err != nil {
			fmt.Printf("Server send message failed, err:%v\n", err)
		}
		fmt.Printf("server send message :%v \n", content)
	}
}
